package com.coder.rental.security;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.NumberWithFormat;
import cn.hutool.core.date.DateTime;
import cn.hutool.jwt.JWTPayload;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.coder.rental.entity.User;
import com.coder.rental.utils.JwtUtils;
import com.coder.rental.utils.RedisUtils;
import com.coder.rental.utils.ResultCode;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.collections4.Put;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 登录成功处理器
 */
@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {

    @Autowired
    private RedisUtils redisUtils;


    /**
     *
     * @param request 请求
     * @param response 响应
     * @param authentication 认证
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        //客户端响应的内容类型是json
        response.setContentType("application/json;charset=utf-8");
        //从认证里面获取到用户的信息
        User user = (User) authentication.getPrincipal();

        //生成token的处理,并转化成json格式响应回去
        Map<String, Object> map = new HashMap<>(){
            {
                put("username",user.getUsername());
                put("userid",user.getId());
            }
        };
        String token=JwtUtils.createToken(map);

        //解析token过期时间,并构建认证结果对象
        AuthenticationResult authenticationResult = new AuthenticationResult();
        NumberWithFormat chaim=(NumberWithFormat) JwtUtils.parseToken(token).getClaim(JWTPayload.EXPIRES_AT);
        long expireTime = Convert.toDate(chaim).getTime();
        authenticationResult.setId(user.getId()).setToken(token).setCode(ResultCode.SUCCESS).setExpireTime(expireTime);

        //获取一个结果,将认证结果转化为JSON字符串
        String result= JSON.toJSONString(authenticationResult,
                SerializerFeature.DisableCircularReferenceDetect);

        //获取输出流,并向客户端发送认证的结果
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(result.getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();

        //把token放入Redis数据库中,并设置过期时间
        String tokenKey="token:token";
        long nowTime = DateTime.now().getTime();
        long time=expireTime- nowTime;
        redisUtils.set(tokenKey,token,time/1000);
        System.out.println(token);
    }
}
